package com.gurun.gateway;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.google.gson.Gson;
import com.gurun.base.Logger;
import com.gurun.base.utils.ToastManager;
import com.gurun.model.bean.event_bean.PushMessageEvent;
import com.gurun.model.bean.gateway.ReportGatewayDataResultBean;
import com.gurun.model.bean.gateway.command.CommandDataModel;
import com.gurun.model.bean.gateway.command.GateWayCommandFromPushModel;
import com.gurun.model.bean.gateway.command.GateWayCommandModel;
import com.lumi.max.jnicall.jnicall;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

/**
 * Created by harry on 2018/3/15.
 */

public class MainService extends Service implements jnicall.NotifyCallback {

    private static final int HANDER_WHAT_ALLOWJOIN = 1;//允许设备入网
    private static final int HANDER_WHAT_DISABLEJOIN = 2;//不允许设备入网
    private static final int HANDER_WHAT_ENABLE_READ_OK = 3;
    private static final int HANDER_WHAT_CHECK_DEVICE_ONLINE = 4;//检查设备是否还在线
    private static final int HANDER_WHAT_SEND_TO_SERVER_HEARTBEAT = 5;//像服务器发送心跳包
    private static final int ALLOWJOIN_TIME = 30 * 1000;//允许设备入网等待时间
    private static final int CHECK_ONLINE_TIME = 30 * 1000;//检测设备是否在线心跳时间
    private static final int SEND_TO_SERVER_HEARTBEAT_TIME = 3 *60* 1000;//像服务器发送心跳包间隔时间
    private jnicall call;

    private Handler mHander = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case HANDER_WHAT_ALLOWJOIN:
                    if (isDeviceOpen()) {
                        call.allowJoin();
                        Logger.d("allowJoin=======");
                    }
                    break;

                case HANDER_WHAT_DISABLEJOIN:
                    if (isDeviceOpen()) {
                        call.disableJoin();
                        Logger.d("disableJoin=======");
                    }
                    break;

                case HANDER_WHAT_ENABLE_READ_OK:
                    reportDataToServer(CommandFactory.getEnableReadOkReportCommand(MainService.this), null, false);
                    mHander.sendEmptyMessageDelayed(HANDER_WHAT_CHECK_DEVICE_ONLINE, CHECK_ONLINE_TIME);
                    ToastManager.show(MainService.this, "测试提示：网关启动成功", Toast.LENGTH_LONG);
                    break;
                case HANDER_WHAT_CHECK_DEVICE_ONLINE:
                    if (!isDeviceOpen()) {
                        //TODO 需要处理掉线（拔掉）情况
                    } else {
                        mHander.sendEmptyMessageDelayed(HANDER_WHAT_CHECK_DEVICE_ONLINE, CHECK_ONLINE_TIME);
                    }
                    break;
                case HANDER_WHAT_SEND_TO_SERVER_HEARTBEAT:
                    reportDataToServer(CommandFactory.getEnableReadOkHeartbeatCommand(MainService.this), null, false);
                    mHander.sendEmptyMessageDelayed(HANDER_WHAT_SEND_TO_SERVER_HEARTBEAT,SEND_TO_SERVER_HEARTBEAT_TIME);
                    break;
            }
        }
    };

    @Override
    public void onCreate() {
        initGateWay();
        mPresenter = new GatewayContract.GatewayPresenter(this);
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        super.onCreate();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void notifyReadDataCallback(String data) {
        GateWayCommandModel gateWayCommandModel = CommandFactory.stringCommandToModel(data);
        if (gateWayCommandModel != null) {
            if (mPresenter == null) {
                mPresenter = new GatewayContract.GatewayPresenter(this);
            }
            if ("zigbee_join".equals(gateWayCommandModel.getCmd())) {//如果是新设备加入
                mPresenter.deviceJoin(gateWayCommandModel, new GatewayContract.DeviceJoinedCallBack() {
                    @Override
                    public void onDeviceJoined(GateWayCommandModel gateWayCommandModel1) {
                        if (gateWayCommandModel1 != null) {
                            reportDataToServer(CommandFactory.getRemoveCommand(MainService.this, gateWayCommandModel1), CommandFactory.getJoinCommand(MainService.this, gateWayCommandModel1), false);
                        }
                    }
                });
            } else if ("remove_device".equals(gateWayCommandModel.getCmd())) {
                mPresenter.removeBySid(gateWayCommandModel);
            } else if ("update_device".equals(gateWayCommandModel.getCmd())) {
                mPresenter.updateShortId(gateWayCommandModel);
            } else {//否则直接上报
                reportDataToServer(data, null, true);
            }
        }
    }

    @Override
    public void enableReadOk() {
        mHander.sendEmptyMessageDelayed(HANDER_WHAT_ENABLE_READ_OK, 2000);
        mHander.removeMessages(HANDER_WHAT_SEND_TO_SERVER_HEARTBEAT);
        mHander.sendEmptyMessageDelayed(HANDER_WHAT_SEND_TO_SERVER_HEARTBEAT,2000);
    }

    private void initGateWay() {
        call = jnicall.getJnicall("PL2303");//TN147
        call.registerCallback(this);
        new Thread(new Runnable() {
            @Override
            public void run() {
                call.open_dongle(getApplicationContext());
                call.startResendOtaThread();
            }
        }).start();
        call.loadDeviceInfo(getApplicationContext());
    }

    private boolean isDeviceOpen() {
        if (call != null && call.isDeviceOpen()) {
            return true;
        }
        return false;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        initGateWay();//TODO 由于sdk经常没反应，所以将初始化移动到这里，方便启动应用就去重新初始化一次。后面稳定后需要改到oncreate方法中。
        if (call != null) {
            call.iniDevice(getApplicationContext());
            if (call.getDevCount() > 0) {
                call.connectFunction(this);
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        onDestoryCall();
    }

    private void onDestoryCall() {
        if (call != null) {
            call.enableRead(false);
            call.disconnectFunction();
            call.removeCallback(this);
        }
    }

    //====================================与服务器交互相关==========================================

    private GatewayContract.GatewayPresenter mPresenter;

    /**
     * 上报数据到服务器
     *
     * @param data
     * @param nextReportData 如果这个不为空，那就表示需要继续上报这个数据
     */
    private void reportDataToServer(String data, final String nextReportData, final boolean needQueryDataFromDatabase) {
        if (mPresenter == null) {
            mPresenter = new GatewayContract.GatewayPresenter(this);
        }
        mPresenter.reportDataToServer(data, needQueryDataFromDatabase, new GatewayContract.DataCallBack() {
            @Override
            public void onComplete() {

            }

            @Override
            public void onLoading() {

            }

            @Override
            public void onLoaded(ReportGatewayDataResultBean datas) {
                if (!TextUtils.isEmpty(nextReportData)) {
                    reportDataToServer(nextReportData, null, needQueryDataFromDatabase);
                }
            }

            @Override
            public void onError(String msg) {

            }
        });
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void recevPushMessage(PushMessageEvent event) {
        if (event != null) {
            String message = event.getMessage();
            if (!TextUtils.isEmpty(message)) {
                handlePushMessage(message);
            }
        }
    }

    private void handlePushMessage(String message) {
        GateWayCommandFromPushModel.CommandModel commandModel = CommandFactory.stringCommandToModelForPush(message);
        if (commandModel != null) {
            if ("permit".equals(commandModel.getCmd())) {//允许设备入网
                mHander.removeMessages(HANDER_WHAT_DISABLEJOIN);
                mHander.sendEmptyMessage(HANDER_WHAT_ALLOWJOIN);
                mHander.sendEmptyMessageDelayed(HANDER_WHAT_DISABLEJOIN, ALLOWJOIN_TIME);
            } else if ("write".equals(commandModel.getCmd())) {//写命令
                if (call != null) {
                    Gson gson = new Gson();
                    GateWayCommandFromPushModel gateWayCommandModel = gson.fromJson(message, GateWayCommandFromPushModel.class);
                    String data = gateWayCommandModel.getData();
                    if (!TextUtils.isEmpty(data)){
                        Logger.d("write datas:"+data);
                        call.write(data);
                    }
                }
            }
        }
    }
}
